package com.service.healthycode.service.impl;

import com.service.config.utils.IdUtil;
import com.service.config.utils.ModelMapperUtil;
import com.service.config.utils.Result;
import com.service.healthycode.dao.*;
import com.service.healthycode.dto.DangerUserDto;
import com.service.healthycode.dto.TerminalListDto;
import com.service.healthycode.dto.TouchInfoDto;
import com.service.healthycode.entity.*;
import com.service.healthycode.service.AdminService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author: hjl
 * @date: 2022/04/13 14:39
 * @description：
 */
@Service
@Slf4j
public class AdminServiceImpl implements AdminService {
    @Resource
    private DangerUserDao dangerUserDao;
    @Resource
    private TouchUserDao touchUserDao;
    @Resource
    private UserHealthRecordsDao healthRecordsDao;
    @Resource
    private UserDao userDao;
    @Resource
    private TerminalListDao terminalListDao;

    @Override
    public Result addDangerUser(DangerUserDto dangerUserDto, UserLoginRecords userDto) {
        DangerUser dangerUser = checkDangerUser(dangerUserDto, userDto.getId());

        //判断是否可以添加
        List<DangerUser> dangerUsers = dangerUserDao.queryByMac(dangerUserDto.getTerminalMac());
        if (!dangerUsers.isEmpty()){
            return Result.failure("当前终端已添加，请取消后再重新添加");
        }

        if (null == dangerUser) {
            return Result.failure(10016, "数据有误，请重新上传!");
        }
        dangerUser.setId(IdUtil.getStringId());
        dangerUser.setCreateTime(new Date());
        dangerUser.setOrigin(0);

        //添加风险人员
        dangerUserDao.addDanger(dangerUser);
        //生成次风险人员,如果录入的风险人员是低风险，则接触用户无风险，即不需要录入到接触表中
        if (dangerUser.getStatus() != 1) {
            List<TouchInfo> touchInfoList = new ArrayList<>();
            touchInfoList.addAll(addTouchUser(dangerUser.getStatus(), dangerUser.getTerminalMac(), dangerUser.getTime(), dangerUser.getStartDate(), dangerUser.getEndDate(), dangerUser.getId(), "",userDto.getId(),touchInfoList));
            if (!touchInfoList.isEmpty()){
                //去重
                ArrayList<TouchInfo> touchInfos = touchInfoList.stream().collect(Collectors
                        .collectingAndThen(
                                Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(TouchInfo::getId))),
                                ArrayList::new));
                //排除dangerUser
                List<TouchInfo> collect = touchInfos.stream().filter(t -> t.getTerminalMac().equals(dangerUser.getTerminalMac())).collect(Collectors.toList());
                if (!collect.isEmpty()){
                    touchInfos.removeAll(collect);
                }

                //相同终端选择状态最严重的
                Map<String, List<TouchInfo>> collect2 = touchInfos.stream().filter(d -> touchInfos.stream().filter(d2 -> d2.getTerminalMac().equals(d.getTerminalMac())).count() > 1)
                        .collect(Collectors.groupingBy(TouchInfo::getTerminalMac));
                List<TouchInfo> touchInfos1 = new ArrayList<>();
                collect2.entrySet().forEach(e -> {
                    Integer status = e.getValue().stream().max(Comparator.comparing(TouchInfo::getStatus)).get().getStatus();
                    touchInfos1.addAll(e.getValue().stream().filter(t->t.getStatus().equals(status)).collect(Collectors.toList()));
                });
                collect2.entrySet().forEach(e -> touchInfos.removeAll(e.getValue()));
                touchInfos.addAll(touchInfos1);

                touchUserDao.addTouchUserList(touchInfos);
            }
        }
        //添加用户健康记录
        addUserHealthRecord(dangerUser);

        return Result.ok();
    }

    /**
     * 更新风险人员
     * @param dangerUserDto 风险用户数据
     * @param userDto 用户数据
     * @return 结果集
     */
    @Override
    public Result updateDangerUser(DangerUserDto dangerUserDto, UserLoginRecords userDto) {
        DangerUser dangerUser1 = dangerUserDao.queryById(dangerUserDto.getId());
        if (null == dangerUser1) {
            return Result.failure("当前用户不存在");
        }

        DangerUser dangerUser = checkDangerUser(dangerUserDto, userDto.getId());
        if (null == dangerUser) {
            return Result.failure(10016, "数据有误，请重新上传!");
        }
        //修改风险用户表
        dangerUserDao.update(dangerUser);

        //修改接触用户表
        //如果只修改了状态，则只需修改接触人员中的状态，不需多次重新查询
        if (!dangerUser.getStatus().equals(dangerUser1.getStatus())
                && dangerUser.getTerminalMac().equals(dangerUser1.getTerminalMac())
                && dangerUser.getStartDate() == dangerUser1.getStartDate()
                && dangerUser.getEndDate() == dangerUser1.getEndDate()
                && dangerUser.getTime().equals(dangerUser1.getTime())) {
            if (dangerUserDto.getStatus() == 1) {
                //删除接触人员信息，因为1为低风险，其次密接为安全
                touchUserDao.delTouchUserByDangerId(dangerUserDto.getId());
            } else {
                touchUserDao.updateTouchUserStatusByDangerId(dangerUserDto.getId(), dangerUserDto.getStatus() - 1);
            }
        } else {
//            addTouchUser(dangerUser,userDto.getId());
        }

        //修改用户健康记录表
        UserInfo userInfo = userDao.queryUserByMac(dangerUser.getTerminalMac());
        UserHealthRecords userHealthRecords = new UserHealthRecords();
        if (null != userInfo) {
            userHealthRecords = ModelMapperUtil.strictMap(userInfo, UserHealthRecords.class);
        }
        userHealthRecords.setDangerId(dangerUser.getId());
        userHealthRecords.setuMac(dangerUser.getTerminalMac());
        userHealthRecords.setStatus(dangerUser.getStatus());
        userHealthRecords.setStartDate(dangerUser.getStartDate());
        userHealthRecords.setEndDate(dangerUser.getEndDate());
        userHealthRecords.setUpdateTime(new Date());
        healthRecordsDao.updateRecord(userHealthRecords);
        return Result.ok();
    }

    /**
     * 查询所有风险用户
     *
     * @return 结果集
     */
    @Override
    public Result queryAllDangerUser() {
        Map<String, Object> map = new HashMap<>(2);
        List<DangerUser> recoveryUsers = dangerUserDao.queryAllRecoveryUser();
        List<DangerUser> dangerUsers = dangerUserDao.queryAllDangerUser();
        map.put("recoveryUsers", recoveryUsers);
        map.put("dangerUsers", dangerUsers);
        return Result.ok().setData(map);
    }

    @Override
    public Result queryDangerUserById(String dangerUserId) {
        DangerUser dangerUser = dangerUserDao.queryDangerUserById(dangerUserId);
        return Result.ok().setData(dangerUser);
    }

    @Override
    public Result delDangerUser(String dangerUserId) {
        DangerUser dangerUser = dangerUserDao.queryById(dangerUserId);
        if (null == dangerUser) {
            return Result.failure("该风险人员不存在！");
        }
        dangerUserDao.deleteById(dangerUserId);
        if (dangerUser.getStatus() != 1) {
            touchUserDao.delTouchUserByDangerId(dangerUser.getId());
        }
        //添加用户健康记录
        healthRecordsDao.delRecordByDangerId(dangerUser.getId());
        return Result.ok();
    }

    /**
     * 添加用户健康记录
     *
     * @param dangerUser 风险用户
     */
    public void addUserHealthRecord(DangerUser dangerUser) {
        UserHealthRecords userHealthRecords = new UserHealthRecords();
        UserInfo userInfo = userDao.queryUserByMac(dangerUser.getTerminalMac());
        if (null != userInfo) {
            userHealthRecords = ModelMapperUtil.strictMap(userInfo, UserHealthRecords.class);
        }
        userHealthRecords.setId(IdUtil.getStringId());
        userHealthRecords.setDangerId(dangerUser.getId());
        userHealthRecords.setuMac(dangerUser.getTerminalMac());
        userHealthRecords.setStatus(dangerUser.getStatus());
        userHealthRecords.setStartDate(dangerUser.getStartDate());
        userHealthRecords.setEndDate(dangerUser.getEndDate());
        userHealthRecords.setAddDate(new Date());
        userHealthRecords.setUpdateTime(new Date());
        healthRecordsDao.addRecourd(userHealthRecords);
    }

    /**
     * 添加接触的风险用户
     * @param status 状态
     * @param terminalMac 终端mac
     * @param time 阈值时间
     * @param startDate 开始时间
     * @param endDate 结束时间
     * @param dangerId 录入风险终端的id
     * @param parentId 父传染终端的id
     * @param adminId 管理员id
     */
    public List<TouchInfo> addTouchUser(Integer status, String terminalMac, Integer time, Date startDate, Date endDate, String dangerId, String parentId, String adminId,List<TouchInfo> touchInfoList) {
        if (status <= 1){
            return touchInfoList;
        }
        //查询该终端在该时间段内所有连接过的连接信息
        List<TerminalList> terminalLists = terminalListDao.queryByTimeAndMac(terminalMac,startDate,endDate,time);
        //查询该风险用户在时间段内连接过的所有AP的连接用户(需要排除风险用户)
        List<TerminalListDto> terminalDtos = new ArrayList<>();
        for (TerminalList terminal : terminalLists) {
            //查询这个时间段内该危险终端在terminal这个AP下的起始时间
            Map<String, Date> map = selectStartAndEndTime(startDate, endDate, terminal);
            //这个起始时间段内感染到的终端有哪些
            List<TerminalList> terminalList = terminalListDao.queryByApAndTime(terminal.getApMac(), map.get("startTime"), map.get("endTime"), time);
            //排除当前terminal终端的可能
            List<TerminalList> list = terminalList.stream().filter(t -> !t.getTerminalMac().equals(terminal.getTerminalMac())).collect(Collectors.toList());
            //排除重复终端的可能
            Map<String, List<TerminalList>> collect2 = list.stream().filter(d -> list.stream().filter(d2 -> d2.getTerminalMac().equals(d.getTerminalMac())).count() > 1)
                    .collect(Collectors.groupingBy(TerminalList::getTerminalMac));
            List<TerminalList> list2 = new ArrayList<>();
            collect2.entrySet().forEach(e -> list2.add(e.getValue().stream().max(Comparator.comparing(TerminalList::getStatus)).get()));
            collect2.entrySet().forEach(e -> list.removeAll(e.getValue()));
            list.addAll(list2);

            if (!list.isEmpty()){
                //计算次风险在该AP上的连接时间和接触时间
                terminalDtos.addAll(calculateTime(map.get("startTime"), map.get("endTime"),list));
            }
        }

        if (!terminalDtos.isEmpty()) {
            //遍历查询到的所有次密接终端，生成接触对象，插入到接触表中
            List<TouchInfo> touchInfos = new ArrayList<>();
            terminalDtos.forEach(dto -> {
                TouchInfo t = new TouchInfo();
                t.setId(IdUtil.getStringId());
                t.setTerminalMac(dto.getTerminalMac());
                t.setTerminalId(dto.getId());
                t.setApMac(dto.getApMac());
                t.setDangerId(dangerId);
                t.setParentId(parentId);
                t.setUpdateTime(new Date());
                t.setStatus(status - 1);
                t.setStayTime(dto.getStayTime());
                t.setTouchTime(dto.getTouchTime());
                t.setStartDate(startDate);
                t.setEndDate(endDate);
                t.setTouchStartTime(dto.getTouchStartTime());
                t.setTouchEndTime(dto.getTouchEndTime());
                t.setCreateTime(new Date());
                t.setAdminId(adminId);
                t.setOrigin(1);
                touchInfos.add(t);
            });
            getTouchInfos(touchInfos);
            touchInfoList.addAll(touchInfos);

//            touchUserDao.addTouchUserList(touchInfos);
            for (TouchInfo touchInfo : touchInfos) {
                //计算接触用户变成风险人员的时间
                Calendar instance = Calendar.getInstance();
                instance.setTime(touchInfo.getTouchStartTime());
                instance.add(Calendar.MINUTE,time);
                addTouchUser(touchInfo.getStatus(),touchInfo.getTerminalMac(),time,instance.getTime(),new Date(),"",touchInfo.getId(),adminId,touchInfoList);
            }
        }


        return touchInfoList;
    }


    /**
     * AP和传染源终端的交叉时间
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @param terminal 终端
     * @return 交叉时间(用来筛选)
     */
    public  Map<String,Date> selectStartAndEndTime(Date startTime,Date endTime,TerminalList terminal){
        Map<String, Date> map=new HashMap<>();
        //计算接触时间
        if (startTime.getTime() >= terminal.getOnLineTime().getTime()) {
            if (terminal.getOffLineTime() == null && endTime.getTime() >= System.currentTimeMillis()) {
                map.put("startTime",startTime);
                map.put("endTime",new Date());
            } else if ((terminal.getOffLineTime() == null && endTime.getTime() < System.currentTimeMillis())
                    || (terminal.getOffLineTime().getTime() > endTime.getTime())) {
                map.put("startTime",startTime);
                map.put("endTime",endTime);
            } else if (terminal.getOffLineTime().getTime() > startTime.getTime()
                    && terminal.getOffLineTime().getTime() <= endTime.getTime()) {
                map.put("startTime",startTime);
                map.put("endTime",terminal.getOffLineTime());
            }
        } else if (startTime.getTime() < terminal.getOnLineTime().getTime()) {
            if (terminal.getOffLineTime() == null && endTime.getTime() >= System.currentTimeMillis()) {
                map.put("startTime",terminal.getOnLineTime());
                map.put("endTime",new Date());
            } else if ((terminal.getOffLineTime() == null && endTime.getTime() < System.currentTimeMillis())
                    || (terminal.getOffLineTime().getTime() >= endTime.getTime())) {
                map.put("startTime",terminal.getOnLineTime());
                map.put("endTime",endTime);
            } else if (terminal.getOffLineTime().getTime() <= endTime.getTime()) {
                map.put("startTime",terminal.getOnLineTime());
                map.put("endTime",terminal.getOffLineTime());
            }
        }
        return map;
    }

    /**
     * 计算风险用户与接触用户的接触时间，以及接触用户在这个ap的逗留时间
     * @param startDate 风险用户的开始时间
     * @param endDate   风险用户的结束时间
     * @param terminalList 风险用户接触过的终端
     * @return 风险用户接触过的终端集合，补充了风险用户接触过的终端的接触时间和逗留时间
     */
    private List<TerminalListDto> calculateTime(Date startDate, Date endDate, List<TerminalList> terminalList) {
        List<TerminalListDto> terminalListDtos = ModelMapperUtil.strictMapList(terminalList, TerminalListDto.class);
        for (TerminalListDto dto : terminalListDtos) {
            //计算逗留时间
            if (dto.getOffLineTime() != null) {
                dto.setStayTime(getDatePoor(dto.getOffLineTime(), dto.getOnLineTime()));
            } else {
                dto.setStayTime(getDatePoor(new Date(), dto.getOnLineTime()));
            }
            //计算接触时间
            if (startDate.getTime() >= dto.getOnLineTime().getTime()) {
                if (dto.getOffLineTime() == null && endDate.getTime() >= System.currentTimeMillis()) {
                    setTouchStartAndEndTime(dto, new Date(), startDate);
                    dto.setTouchTime(getDatePoor(new Date(), startDate));
                } else if ((dto.getOffLineTime() == null && endDate.getTime() < System.currentTimeMillis())
                        || (dto.getOffLineTime().getTime() > endDate.getTime())) {
                    setTouchStartAndEndTime(dto, endDate, startDate);
                    dto.setTouchTime(getDatePoor(endDate, startDate));
                } else if (dto.getOffLineTime().getTime() > startDate.getTime()
                        && dto.getOffLineTime().getTime() <= endDate.getTime()) {
                    setTouchStartAndEndTime(dto, dto.getOffLineTime(), startDate);
                    dto.setTouchTime(getDatePoor(dto.getOffLineTime(), startDate));
                }
            } else if (startDate.getTime() < dto.getOnLineTime().getTime()) {
                if (dto.getOffLineTime() == null && endDate.getTime() >= System.currentTimeMillis()) {
                    setTouchStartAndEndTime(dto, new Date(), dto.getOnLineTime());
                    dto.setTouchTime(getDatePoor(new Date(), dto.getOnLineTime()));
                } else if ((dto.getOffLineTime() == null && endDate.getTime() < System.currentTimeMillis())
                        || (dto.getOffLineTime().getTime() >= endDate.getTime())) {
                    setTouchStartAndEndTime(dto, endDate, dto.getOnLineTime());
                    dto.setTouchTime(getDatePoor(endDate, dto.getOnLineTime()));
                } else if (dto.getOffLineTime().getTime() <= endDate.getTime()) {
                    setTouchStartAndEndTime(dto, dto.getOffLineTime(), dto.getOnLineTime());
                    dto.setTouchTime(getDatePoor(dto.getOffLineTime(), dto.getOnLineTime()));
                }
            }
        }
        return terminalListDtos;
    }

    /**
     * 添加接触的风险用户
     * @param dangerUserDto 风险用户
     */
    @Override
    public Result queryTouchUser(DangerUserDto dangerUserDto,String adminId) {
        DangerUser dangerUser = checkDangerUser(dangerUserDto, adminId);
        if (null ==dangerUser){
            return Result.failure("参数错误");
        }
        //查询用户表中是否存在该风险用户
        UserInfo userInfo = userDao.queryUserByMac(dangerUser.getTerminalMac());
        //查询该终端在该时间段内所有连接过的连接信息
        List<TerminalList> terminalLists = terminalListDao.queryByTimeAndMac(dangerUser);

        //查询该风险用户在时间段内连接过的所有AP的连接用户(需要排除风险用户)
        List<TerminalListDto> terminals = new ArrayList<>();
        for (TerminalList terminal : terminalLists) {
            List<TerminalList> terminalList = terminalListDao.queryByApAndTime(terminal.getApMac(), dangerUser.getStartDate(), dangerUser.getEndDate(), dangerUser.getTime());
            List<TerminalList> collect = terminalList.stream().filter(t -> t.getTerminalMac().equals(terminal.getTerminalMac())).collect(Collectors.toList());
            if (!collect.isEmpty()){
                terminalList.removeAll(collect);
            }

            if (!terminalList.isEmpty()){
                //计算在该ap上的连接时间和接触时间
                terminals.addAll(calculateTime(dangerUser.getStartDate(),dangerUser.getEndDate(),terminalList));
            }
        }

        List<TouchInfo> touchInfos = new ArrayList<>();
        if (!terminals.isEmpty()) {
            //排除当前的风险用户
            List<TerminalListDto> terminalDtos = terminals.stream().filter(t -> !t.getApMac().equals(dangerUser.getTerminalMac())).collect(Collectors.toList());

            //遍历查询到的所有次密接终端，生成接触对象，插入到接触表中
            List<TerminalListDto> collect = terminalDtos.stream().distinct().collect(Collectors.toList());
            collect.forEach(c -> {
                TouchInfo t = new TouchInfo();
                t.setId(IdUtil.getStringId());
                t.setTerminalMac(c.getTerminalMac());
                t.setApMac(c.getApMac());
                t.setDangerId(dangerUser.getId());
                t.setUpdateTime(dangerUser.getUpdateTime());
                t.setStatus(dangerUser.getStatus() - 1);
                t.setStayTime(c.getStayTime());
                t.setTouchTime(c.getTouchTime());
                if (userInfo != null) {
                    t.setUId(userInfo.getId());
                }
                t.setTouchStartTime(c.getTouchStartTime());
                t.setTouchEndTime(c.getTouchEndTime());
                t.setCreateTime(new Date());
                touchInfos.add(t);
            });
            if (!touchInfos.isEmpty()){
                getTouchInfos(touchInfos);
                return Result.ok().setData(ModelMapperUtil.strictMapList(touchInfos, TouchInfoDto.class));
            }
            return Result.ok().setData(touchInfos);
        }
        return Result.ok().setData(touchInfos);
    }

    /**
     * 抽取公共代码
     * @param touchInfos
     * @return
     */
    private void getTouchInfos(List<TouchInfo> touchInfos) {
        Map<String, List<TouchInfo>> collect2 = touchInfos.stream().filter(d -> touchInfos.stream().filter(d2 -> d2.getTerminalMac().equals(d.getTerminalMac())).count() > 1)
                .collect(Collectors.groupingBy(TouchInfo::getTerminalMac));
        List<TouchInfo> touchInfos1 = new ArrayList<>();
        collect2.entrySet().forEach(e -> touchInfos1.add(e.getValue().stream().max(Comparator.comparing(TouchInfo::getStatus)).get()));
        collect2.entrySet().forEach(e -> touchInfos.removeAll(e.getValue()));
        touchInfos.addAll(touchInfos1);
    }

    /**
     * 修改风险人员状态
     * @param origin
     * @param status
     * @param id
     * @param userDto
     * @param flag 是否修改下层所有风险人员状态
     * @return
     */
    @Override
    public Result updateDangerUserStatus(Integer origin, Integer status,UserLoginRecords userDto,Boolean flag,String terminalMac) {
        Object obj;
        if (origin.equals(0)){
            if (flag==false){
                //只修改当前终端
                updateStatusByTerminalMac(status,userDto.getId(),terminalMac,origin);
                return Result.ok();
            }else {
                //修改当前
                obj = updateStatusByTerminalMac(status, userDto.getId(), terminalMac, origin);
                if (obj!=null){
                    List<String> dangerIds = ModelMapperUtil.strictMapList(obj, String.class);
                    for (String dangerId : dangerIds) {
                        //递归修改下层所有
                        updateStatusRecursion(dangerId,userDto.getId(),status,0);
                    }
                }

                return Result.ok();
            }
        }else if (origin.equals(1)){
            if (flag==false){
                //只修改当前终端
                updateStatusByTerminalMac(status,userDto.getId(),terminalMac,origin);
                return Result.ok();
            }else {
                //修改当前
                obj = updateStatusByTerminalMac(status, userDto.getId(), terminalMac, origin);
                if (null != obj){
                    List<String> touchIds = ModelMapperUtil.strictMapList(obj, String.class);
                    for (String touchId : touchIds) {
                        //递归修改下层所有
                        updateStatusRecursion(touchId,userDto.getId(),status,1);
                    }
                }
                return Result.ok();
            }
        }else if (origin.equals(2)){
            if (!flag){
                //只修改当前终端
                updateStatusByTerminalMac(status,userDto.getId(),terminalMac,origin);
            }else {
                obj = updateStatusByTerminalMac(status,userDto.getId(),terminalMac,origin);
                if (null != obj){
                    HashMap<Integer, List<String>> map = ModelMapperUtil.strictMap(obj, HashMap.class);
                    if (null != map){
                        List<String> dangerIds = map.get(0);
                        List<String> touchIds = map.get(1);
                        for (String dangerId : dangerIds) {
                            //递归修改下层所有
                            updateStatusRecursion(dangerId,userDto.getId(),status,0);
                        }
                        for (String touchId : touchIds) {
                            //递归修改下层所有
                            updateStatusRecursion(touchId,userDto.getId(),status,1);
                        }
                    }
                }
            }
            return Result.ok();
        }
        return Result.failure("参数有误");
    }

    /**
     * 修改终端状态的递归
     * @param terminalId 终端id
     * @param adminId 管理员id
     * @param status 状态
     * @param origin 来源：0-danger;1-touch
     */
    public void updateStatusRecursion(String terminalId,String adminId,Integer status,Integer origin){
        if (origin.equals(1)){
            List<TouchInfo> touchInfos = touchUserDao.queryNextLevelByGeneral(terminalId);
            if (touchInfos.isEmpty()){
                delSafeTerminal();
                return;
            }
            updateRecursion(adminId, status, touchInfos);
        }else if (origin.equals(0)){
            List<TouchInfo> touchInfos = touchUserDao.queryNextLevelByRoot(terminalId);
            if (touchInfos.isEmpty()){
                delSafeTerminal();
                return;
            }
            updateRecursion(adminId, status, touchInfos);
        }
    }

    /**
     * 抽取公共代码
     * @param adminId 管理员id
     * @param status 状态
     * @param touchInfos touch集合
     */
    private void updateRecursion(String adminId, Integer status, List<TouchInfo> touchInfos) {
        if (!touchInfos.isEmpty()) {
            //查询下一层集合
            List<String> ids = touchInfos.stream().map(TouchInfo::getId).collect(Collectors.toList());
            //修改下一层状态
            touchUserDao.updateStatusBatch(ids, adminId, status - 1);
            for (String termId : ids) {
                updateStatusRecursion(termId, adminId, status - 1, 1);
            }
        }
    }

    /**
     * 修改danger表中终端状态
     * @param status
     * @param terminalId
     * @param adminId
     */
    public void updateStatusOfTouchTerminal(Integer status,String terminalId,String adminId,String terminalMac){
        //只修改当前终端
        TouchInfo touchInfo = new TouchInfo();
        touchInfo.setStatus(status);
//        touchInfo.setId(terminalId);
        touchInfo.setTerminalMac(terminalMac);
        touchInfo.setAdminId(adminId);
        touchInfo.setUpdateTime(new Date());
        touchUserDao.update(touchInfo);
    }

    /**
     * 修改touch表中终端状态
     * @param status
     * @param terminalId
     * @param adminId
     */
    public void updateStatusOfDangerTerminal(Integer status,String terminalId,String adminId,String terminalMac){
        //只修改当前终端
        DangerUser dangerUser = new DangerUser();
//        dangerUser.setId(terminalId);
        dangerUser.setTerminalMac(terminalMac);
        dangerUser.setStatus(status);
        dangerUser.setAdminId(adminId);
        dangerUser.setUpdateTime(new Date());
        //通过mac地址修改终端状态
        dangerUserDao.updateStatusByTerminalMac(dangerUser);
    }

    /**
     * 根据终端mac修改终端状态
     * @param status
     * @param adminId
     * @param terminalMac
     */
    public Object updateStatusByTerminalMac(Integer status,String adminId,String terminalMac,Integer origin){
        DangerUser dangerUser = new DangerUser();
        dangerUser.setTerminalMac(terminalMac);
        dangerUser.setStatus(status);
        dangerUser.setAdminId(adminId);
        dangerUser.setUpdateTime(new Date());
        //通过mac地址修改终端状态
        dangerUserDao.updateStatusByTerminalMac(dangerUser);

        //只修改当前终端
        TouchInfo touchInfo = new TouchInfo();
        touchInfo.setStatus(status);
        touchInfo.setTerminalMac(terminalMac);
        touchInfo.setAdminId(adminId);
        touchInfo.setUpdateTime(new Date());
        touchUserDao.updateStatusByTerminalMac(touchInfo);
        //删除安全终端数据
        delSafeTerminal();

        if (origin.equals(0)){
            List<DangerUser> dangerUsers = dangerUserDao.queryByMac(terminalMac);
            if (!dangerUsers.isEmpty()){
                List<String> dangerIds = dangerUsers.stream().map(DangerUser::getId).collect(Collectors.toList());
                return dangerIds;
            }
            return null;
        }else if (origin.equals(1)){
            List<TouchInfo> touchInfos = touchUserDao.queryByMac(terminalMac);
            if (!touchInfos.isEmpty()){
                List<String> touchIds = touchInfos.stream().map(TouchInfo::getId).collect(Collectors.toList());
                return touchIds;
            }
            return null;
        }else if (origin.equals(2)){

            List<DangerUser> dangerUsers = dangerUserDao.queryByMac(terminalMac);
            List<TouchInfo> touchInfos = touchUserDao.queryByMac(terminalMac);

            Map<Integer,List<String>> map = new HashMap<>();
            if (!dangerUsers.isEmpty()){
                List<String> dangerIds = dangerUsers.stream().map(DangerUser::getId).collect(Collectors.toList());
                map.put(0,dangerIds);
            }
            if (!touchInfos.isEmpty()){
                List<String> touchIds = touchInfos.stream().map(TouchInfo::getId).collect(Collectors.toList());
                map.put(1,touchIds);
            }
            return map;
        }
        return null;
    }


    /**
     * 查询所有上传的风险人员
     * @return 结果集
     */
    @Override
    public Result queryUploadRiskUser() {
        List<DangerUser> dangerUsers = dangerUserDao.queryAllDangerUser();
        return Result.ok().setData(dangerUsers);
    }


    /**
     * 检查传入数据
     * @param dangerUserDto 风险用户dto
     * @param adminId 管理员id
     * @return 返回风险用户
     */
    public DangerUser checkDangerUser(DangerUserDto dangerUserDto, String adminId) {
        if (dangerUserDto.getTime() == null || dangerUserDto.getTime() == 0) {
            dangerUserDto.setTime(10);
        }
        if (dangerUserDto.getTerminalMac() == null || "".equals(dangerUserDto.getTerminalMac())
                || dangerUserDto.getStartDate() == null || dangerUserDto.getEndDate() == null) {
            return null;
        }
        DangerUser dangerUser = ModelMapperUtil.strictMap(dangerUserDto, DangerUser.class);
        dangerUser.setAdminId(adminId);
        dangerUser.setUpdateTime(new Date());
        return dangerUser;
    }

    /**
     * 计算时间差。返回分钟数
     * @param startDate 开始时间
     * @param endDate 结束时间
     * @return 时间差(分钟)
     */
    public long getDatePoor(Date endDate,Date startDate){
        return (endDate.getTime() - startDate.getTime()) / (1000 * 60);
    }

    public void delSafeTerminal(){
        dangerUserDao.delByStatus();
        touchUserDao.delByStatus();
    }


    /**
     * 设置接触终端的接触开始时间和接触结束时间
     * @param terminalListDto 接触终端
     * @param touchEndTime 接触结束时间
     * @param touchStartTime 接触开始时间
     */
    public void setTouchStartAndEndTime(TerminalListDto terminalListDto,Date touchEndTime,Date touchStartTime){
        terminalListDto.setTouchEndTime(touchEndTime);
        terminalListDto.setTouchStartTime(touchStartTime);
    }
}
